<html>
<head><meta charset="utf-8"><title>lerp API design · t-libs · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/index.html">t-libs</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html">lerp API design</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="244050240"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244050240" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244050240">(Jun 27 2021 at 05:07)</a>:</h4>
<p>Coming from <a href="https://github.com/rust-lang/rust/issues/86269">#86269</a>, to discuss the signature for <code>lerp</code>. I'll summarize what's been said in the issue so far shortly.</p>



<a name="244052210"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244052210" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244052210">(Jun 27 2021 at 06:20)</a>:</h4>
<p>Summary as I see it so far</p>
<p><a href="https://github.com/rust-lang/rust/issues/86269#issuecomment-864347515">https://github.com/rust-lang/rust/issues/86269#issuecomment-864347515</a>, data collection by <span class="user-mention" data-user-id="132829">@Christopher Durham</span> </p>
<p><code>nalgebra</code>, <code>euclid</code>, <code>glam</code>, <code>cgmath</code>, <code>kurbo</code>, and <code>ultraviolet</code> all provide <code>v0.lerp(v1, t)</code>. <code>emath</code> provides <code>lerp(v0..=v1, t)</code>, and <code>vek</code> provides <code>lerp(v0, v1, t)</code>.</p>
<p><a href="https://github.com/rust-lang/rust/pull/86462#issuecomment-865391638">https://github.com/rust-lang/rust/pull/86462#issuecomment-865391638</a>, data collection by <span class="user-mention" data-user-id="132829">@Christopher Durham</span> </p>
<p>HLSL, GLSL, C++20, Unity, Unreal, Godot, GameMaker, and p5.js provide <code>lerp(v0, v1, t)</code>.  Godot, Blender, and pygame provide <code>v0.lerp(v1, t)</code>. numpy provides <code>lerp(t, v0, v1)</code>.</p>
<p><a href="https://github.com/rust-lang/rust/pull/86462#issuecomment-867162705">https://github.com/rust-lang/rust/pull/86462#issuecomment-867162705</a> notes that vectorized <code>lerp</code> (e.g. <code>lerp(f32x4, f32x4, f32x4)</code>) will prefer to _not_ use <code>RangeInclusive</code>.</p>
<p><a href="https://github.com/rust-lang/rust/pull/86462#issuecomment-867200253">https://github.com/rust-lang/rust/pull/86462#issuecomment-867200253</a> concurs that the use of <code>RangeInclusive</code> implies that only an increasing range would be allowed, but <code>lerp</code> wants to support lerping in either direction.</p>
<p><a href="https://github.com/rust-lang/rust/pull/86462#issuecomment-867170825">https://github.com/rust-lang/rust/pull/86462#issuecomment-867170825</a> notes that <code>t.lerp(v0, v1)</code> extends nicely to <code>t.qarp(v0, v1, v2)</code> and <code>t.curp(v0, v1, v2, v3)</code>.</p>
<p><a href="https://github.com/rust-lang/rust/issues/86269#issuecomment-869098042">https://github.com/rust-lang/rust/issues/86269#issuecomment-869098042</a> notes that (without std traits) 3rd party libraries would not be able to provide <code>t.lerp(v0, v1)</code> for their own types, a problem which does not apply to <code>v0.lerp(v1, t)</code>, due to how method lookup and overloading works.</p>
<p><a href="https://github.com/rust-lang/rust/issues/86269#issuecomment-869098630">https://github.com/rust-lang/rust/issues/86269#issuecomment-869098630</a> calls more attention to the scope of change required for the ecosystem to migrate from <code>v0.lerp(v1, t)</code> to <code>t.lerp(v0, v1)</code>, if std goes with that order and allows 3rd party crates to hook into it.</p>
<p><a href="https://github.com/rust-lang/rust/issues/86269#issuecomment-869099716">https://github.com/rust-lang/rust/issues/86269#issuecomment-869099716</a> notes that this is effectively a double-dispatch problem, with a primary dispatch of the interpolated type, and a secondary dispatch on the bitwidth of <code>t</code> (don't forget this should work for both <code>f32</code> and <code>f64</code>, if not even also other types able to express values in <code>0.0..=1.0</code>).</p>



<a name="244054691"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244054691" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244054691">(Jun 27 2021 at 07:35)</a>:</h4>
<blockquote>
<p>vectorized lerp (e.g. lerp(f32x4, f32x4, f32x4)) will prefer to _not_ use RangeInclusive.</p>
</blockquote>
<p>I'm very convinced by this statement. Particularly with MS moving to windows 11, which basically requires CPUs that will have avx2 as a minimum cpu feature set, it will be an even bigger performance gap to not be using simd when possible.</p>



<a name="244058045"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244058045" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244058045">(Jun 27 2021 at 09:15)</a>:</h4>
<p><span class="user-mention silent" data-user-id="224471">Lokathor</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244054691">said</a>:</p>
<blockquote>
<blockquote>
<p>vectorized lerp (e.g. lerp(f32x4, f32x4, f32x4)) will prefer to _not_ use RangeInclusive.</p>
</blockquote>
<p>I'm very convinced by this statement. Particularly with MS moving to windows 11, which basically requires CPUs that will have avx2 as a minimum cpu feature set, it will be an even bigger performance gap to not be using simd when possible.</p>
</blockquote>
<p>I see no reason to think that vectorized <code>lerp</code>with or without using <code>RangeInclusive</code> will have any performance differences... these should produce identical assembly assuming <code>lerp</code> is inlined:<br>
<span class="user-mention" data-user-id="281757">@Jubilee</span> note that  it's a range where the endpoints are vectors, <em>not</em> a vector of ranges.</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">f</span><span class="p">(</span><span class="n">a</span>: <span class="nc">f32x4</span><span class="p">,</span><span class="w"> </span><span class="n">b</span>: <span class="nc">f32x4</span><span class="p">,</span><span class="w"> </span><span class="n">t</span>: <span class="nc">f32x4</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">f32x4</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">t</span><span class="p">.</span><span class="n">lerp</span><span class="p">(</span><span class="n">a</span><span class="o">..=</span><span class="n">b</span><span class="p">)</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">f</span><span class="p">(</span><span class="n">a</span>: <span class="nc">f32x4</span><span class="p">,</span><span class="w"> </span><span class="n">b</span>: <span class="nc">f32x4</span><span class="p">,</span><span class="w"> </span><span class="n">t</span>: <span class="nc">f32x4</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">f32x4</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">t</span><span class="p">.</span><span class="n">lerp</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="p">)</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="244058105"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244058105" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244058105">(Jun 27 2021 at 09:17)</a>:</h4>
<p>...hm.</p>



<a name="244058149"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244058149" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244058149">(Jun 27 2021 at 09:18)</a>:</h4>
<p>I think that goes bad places in practice considering RangeInclusive's invariants but I could see it as an alternative, I suppose.</p>



<a name="244058302"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244058302" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244058302">(Jun 27 2021 at 09:23)</a>:</h4>
<p>yup, I'm not saying that RangeInclusive is better or worse, I'm just saying vector performance should not be a factor.</p>



<a name="244060773"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244060773" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> The 8472 <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244060773">(Jun 27 2021 at 10:36)</a>:</h4>
<p>Why not change the name to make it clear? <code>val.interpolate_between(start: f32, end: f32)</code>? You still could put doc alias to lerp on it. Although there's some debate around the correct use of doc aliases...</p>



<a name="244060782"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244060782" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> The 8472 <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244060782">(Jun 27 2021 at 10:37)</a>:</h4>
<p>The parameter names already are start and end and those generally show up in IDE context assists, that already might be good enough.</p>



<a name="244061183"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244061183" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244061183">(Jun 27 2021 at 10:49)</a>:</h4>
<p>another option for naming: <code>lerp</code> is a linear Bézier curve, if we might add quadratic and cubic Bézier curves later then we could name the linear Bézier curve <code>t.bezier([start, end])</code>, the quadratic Bézier curve <code>t.bezier([start, c, end])</code>, and the cubic Bézier curve <code>t.bezier([start, c1, c2, end])</code></p>



<a name="244072927"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244072927" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244072927">(Jun 27 2021 at 16:01)</a>:</h4>
<p>I guess that's the other side of this question -- do we want things like Bezier in core?  If not, do we even want lerp?  It doesn't need an intrinsic or anything to implement it, right?</p>



<a name="244076713"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244076713" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244076713">(Jun 27 2021 at 17:36)</a>:</h4>
<p>yeah anyone can just make their own lerp function</p>



<a name="244076935"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244076935" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mara <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244076935">(Jun 27 2021 at 17:42)</a>:</h4>
<p>looks like it's pretty tricky to get a correct one. see all the edge cases handled in that PR that added it</p>



<a name="244077076"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244077076" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244077076">(Jun 27 2021 at 17:46)</a>:</h4>
<p>well part of the "lerp controversy" is that people sometimes legitimately want different formulas because they care about different things. Which isn't to say that we can't provide a "sane default".</p>



<a name="244077095"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244077095" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244077095">(Jun 27 2021 at 17:46)</a>:</h4>
<p>the PR that added it doesn't seem to be handling any edge cases. Also, this tends to be very performance sensitive, so a version like e.g. C++'s (which tries to handle a billion edge cases) is unlikely to ever get used.</p>
<p>i'd actually guess that the version that landed is the same way, since AFIACT it uses the fma call that (unless you compile with a recent <code>-Ctarget-cpu</code> or <code>-Ctarget-feature</code> on a arch that has fused-multiply-accumulate instructions) will compile to a libc invocation.</p>



<a name="244077104"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244077104" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244077104">(Jun 27 2021 at 17:46)</a>:</h4>
<p>I also tend to agree with lokathor, I don't know that this is a good thing to provide, since there are a lot of different choices you can make here.</p>
<p>EDIT: (actually, rereading, I misread lokathor's comment... well, nevertheless...)</p>



<a name="244077175"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244077175" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244077175">(Jun 27 2021 at 17:48)</a>:</h4>
<p>I'd <em>also</em> be fine if the whole function went away and there was just no standard library lerp. Enough people seem to want it though.</p>



<a name="244077753"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244077753" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244077753">(Jun 27 2021 at 18:02)</a>:</h4>
<p>it would be nice to get feedback from prospective users (game developers?) as to what implementation they're currently using and whether this interface/implementation is sufficient</p>



<a name="244077961"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244077961" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mara <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244077961">(Jun 27 2021 at 18:07)</a>:</h4>
<p><span class="user-mention silent" data-user-id="209168">Thom Chiovoloni</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244077095">said</a>:</p>
<blockquote>
<p>the PR that added it doesn't seem to be handling any edge cases.</p>
</blockquote>
<p>are we talking about thes same PR? <a href="https://github.com/rust-lang/rust/pull/85925/files">#85925</a> specifically handles exactness, monoticity and consistency</p>



<a name="244077967"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244077967" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mara <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244077967">(Jun 27 2021 at 18:07)</a>:</h4>
<p>those are very easy to get wrong or implement in a non-performant way</p>



<a name="244078024"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244078024" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244078024">(Jun 27 2021 at 18:08)</a>:</h4>
<p>Unfortunately, the implementation actually currently isn't monotonic</p>



<a name="244078025"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244078025" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244078025">(Jun 27 2021 at 18:08)</a>:</h4>
<p>we weren't talking about the same PR</p>



<a name="244078056"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244078056" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244078056">(Jun 27 2021 at 18:09)</a>:</h4>
<div class="codehilite"><pre><span></span><code>Not monotonic: lerp(0.24997729, 0.27129978, 0.9048672) = 0.42967725
             &gt; lerp(0.2499773 , 0.27129978, 0.9048672) = 0.42967722
</code></pre></div>



<a name="244078121"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244078121" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244078121">(Jun 27 2021 at 18:11)</a>:</h4>
<p><span class="user-mention silent" data-user-id="256342">bstrie</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244077753">said</a>:</p>
<blockquote>
<p>it would be nice to get feedback from prospective users (game developers?) as to what implementation they're currently using and whether this interface/implementation is sufficient</p>
</blockquote>
<p>i'm a game developer (currently independent, although i've worked at studios in the past and have games on steam and the like).</p>
<p>i joked last night with another friend of mine (who is also a game developer) that there's almost no way that this ends up with something usable, which is i guess to be expected (it would be the track record for c++'s efforts here too). i think this kind of thing is probably better left to math libs, who can evaluate the tradeoffs here better.</p>
<p>in my code i don't bother with the f64 version, and have both done lerp as a trait (which I don't do anymore), and as inherent <code>pub fn lerp(self, b: Self, t: f32) -&gt; Self</code> on relevant types. I just do it as <code>a * (1.0 - t) + b * t</code>, and the lack of monotonicity or exactness for <code>a == b</code> has never caused bugs for me (in comparison: poor performance in this sort of code <em>has</em>, so...)</p>



<a name="244078178"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244078178" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244078178">(Jun 27 2021 at 18:12)</a>:</h4>
<p>also again, an implementation that calls to libm::fmaf twice unless you pass special compiler flags is... imo borderline unacceptable</p>



<a name="244078195"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244078195" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244078195">(Jun 27 2021 at 18:13)</a>:</h4>
<p>I definitely agree that we'd want to use loose math that can optimize to FMA rather than requiring FMA</p>



<a name="244078273"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244078273" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mara <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244078273">(Jun 27 2021 at 18:14)</a>:</h4>
<p><span class="user-mention silent" data-user-id="132829">Christopher Durham</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244078056">said</a>:</p>
<blockquote>
<p><div class="codehilite"><pre><span></span><code>Not monotonic: lerp(0.24997729, 0.27129978, 0.9048672) = 0.42967725
             &gt; lerp(0.2499773 , 0.27129978, 0.9048672) = 0.42967722
</code></pre></div><br>
</p>
</blockquote>
<p>i get the opposite results:</p>
<div class="codehilite"><pre><span></span><code>[src/main.rs:11] f32::lerp(0.24997729, 0.27129978, 0.9048672) = 0.42967722
[src/main.rs:12] f32::lerp(0.2499773 , 0.27129978, 0.9048672) = 0.42967725
</code></pre></div>



<a name="244078282"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244078282" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244078282">(Jun 27 2021 at 18:14)</a>:</h4>
<p>I'll test again, maybe I messed something up</p>



<a name="244078356"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244078356" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244078356">(Jun 27 2021 at 18:16)</a>:</h4>
<p>does this call for a whole family of lerp functions that each provide different guarantees?</p>



<a name="244078363"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244078363" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244078363">(Jun 27 2021 at 18:16)</a>:</h4>
<p>Also gamedev (grad student); I've put a lot of time into documenting existing practice in the tracking issue. As far as API, I don't have any preference beyond making sure that the same API works for vector types</p>



<a name="244078442"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244078442" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244078442">(Jun 27 2021 at 18:18)</a>:</h4>
<p>As far as implementation: all of the guarantees aren't all that important if you can bound them to e.g. ±2 ULP, because such drift is negligible in gamedev/graphics</p>



<a name="244078831"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244078831" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244078831">(Jun 27 2021 at 18:26)</a>:</h4>
<p>WRT "aren't that important", are they so unimportant that std could get away with adding or removing any of those guarantees in any arbitrary release? in other words, would these guarantees (or the lack thereof) be part of the stable API?</p>



<a name="244078896"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244078896" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244078896">(Jun 27 2021 at 18:28)</a>:</h4>
<p>With something like <code>lerp</code>, the exact behavior quickly becomes relied upon, even if not explicitly stable.<br>
Also, the performance characteristics are implicitly part of the guarantees, and very important for such a building block.</p>



<a name="244078911"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244078911" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244078911">(Jun 27 2021 at 18:29)</a>:</h4>
<p>I find it hard to think of an "open to change" specification+implementation that would both be open to improvement in the future plus be usable by gamedevs who want <code>lerp</code> to be <em>free</em>.</p>



<a name="244079032"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244079032" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244079032">(Jun 27 2021 at 18:32)</a>:</h4>
<p><span class="user-mention silent" data-user-id="310399">Mara</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244078273">said</a>:</p>
<blockquote>
<p>i get the opposite results:</p>
<p><div class="codehilite"><pre><span></span><code>[src/main.rs:11] f32::lerp(0.24997729, 0.27129978, 0.9048672) = 0.42967722
[src/main.rs:12] f32::lerp(0.2499773 , 0.27129978, 0.9048672) = 0.42967725
</code></pre></div><br>
</p>
</blockquote>
<p>I'm still getting <a href="https://play.rust-lang.org/?version=nightly&amp;mode=release&amp;edition=2018&amp;gist=235d933360a1af9d658ac1bc59a1e432">plenty of montonicity violations</a>:</p>
<div class="codehilite"><pre><span></span><code>Not monotonic:
  lerp(0.000015328364, 0.10231668, 0.85570544) = 0.102328226
  lerp(0.000015328365, 0.10231668, 0.85570544) = 0.10232822
Not monotonic:
  lerp(0.000015401183, 0.10231668, 0.85570544) = 0.102328286
  lerp(0.000015401185, 0.10231668, 0.85570544) = 0.10232828
Not monotonic:
  lerp(0.000015474003, 0.10231668, 0.85570544) = 0.10232834
  lerp(0.000015474005, 0.10231668, 0.85570544) = 0.10232833
Not monotonic:
  lerp(0.00001554682, 0.10231668, 0.85570544) = 0.1023284
  lerp(0.000015546822, 0.10231668, 0.85570544) = 0.10232839
Not monotonic:
  lerp(0.00001561964, 0.10231668, 0.85570544) = 0.10232845
  lerp(0.000015619642, 0.10231668, 0.85570544) = 0.10232844
Not monotonic:
  lerp(0.000015692458, 0.10231668, 0.85570544) = 0.1023285
  lerp(0.00001569246, 0.10231668, 0.85570544) = 0.102328494
Not monotonic:
  lerp(0.000015765278, 0.10231668, 0.85570544) = 0.10232856
  lerp(0.00001576528, 0.10231668, 0.85570544) = 0.102328554
</code></pre></div>



<a name="244079077"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244079077" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244079077">(Jun 27 2021 at 18:34)</a>:</h4>
<p>IMO it seems like the tradeoffs are a bit too subtle to add this to std. If "correct" implementations are slow, and slow implementations are useless, and assuming that std only wants to contain useful things, then the question is whether std wants to deliberately contain an "incorrect" thing. I have to ask, who proposed this for C++, and were they happy with a "useless" implementation being the result? Was their use case different?</p>



<a name="244079174"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244079174" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244079174">(Jun 27 2021 at 18:36)</a>:</h4>
<p>c++ is notorious for doing this, honestly. there's lots of useless stuff in the stdlib std::complex and std::valarray are the same way, and that's just considering numerically-relevant stuff</p>



<a name="244079205"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244079205" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mara <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244079205">(Jun 27 2021 at 18:37)</a>:</h4>
<p><span class="user-mention" data-user-id="132829">@Christopher Durham</span> you have a <code>t</code> where you need a <code>nextt</code>. but yeah, still many not-monotonic results.</p>



<a name="244079249"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244079249" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244079249">(Jun 27 2021 at 18:38)</a>:</h4>
<p><span class="user-mention silent" data-user-id="310399">Mara</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244079205">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="132829">Christopher Durham</span> you have a <code>t</code> where you need a <code>nextt</code>. but yeah, still many not-monotonic results.</p>
</blockquote>
<p>whoops <span aria-label="upside down" class="emoji emoji-1f643" role="img" title="upside down">:upside_down:</span></p>



<a name="244079260"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244079260" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244079260">(Jun 27 2021 at 18:38)</a>:</h4>
<p>Right, I understand C++ is famous for overspecifying, but in the pursuit of being charitable it would be useful to know who specifically proposed this, whether they had a personal stake in the outcome, and what their use case was.</p>



<a name="244079262"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244079262" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244079262">(Jun 27 2021 at 18:38)</a>:</h4>
<p>I continue to wish that C++ papers included any of the motivation, but here's the paper that added <code>std::midpoint</code> and <code>std::lerp</code>: <a href="https://wg21.link/p0811">https://wg21.link/p0811</a></p>



<a name="244079455"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244079455" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244079455">(Jun 27 2021 at 18:45)</a>:</h4>
<p>it's also worth noting that c++ has a notorious problem where game developers aren't part of the standards committees, and instead just complain that the stdlib is unusable for gamedev</p>



<a name="244079527"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244079527" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244079527">(Jun 27 2021 at 18:46)</a>:</h4>
<p>i must admit i'm guilty of doing that when I used c++ and not rust (not that i'd have been qualified to participate in a meaningful way, probably). rust doesn't have that problem, since more of the discussion is in the open</p>



<a name="244079532"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244079532" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244079532">(Jun 27 2021 at 18:46)</a>:</h4>
<p>also it's a lot harder to avoid using the stdlib in rust</p>



<a name="244079618"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244079618" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244079618">(Jun 27 2021 at 18:49)</a>:</h4>
<p>are there consumers of this aside from gamedevs?</p>



<a name="244079694"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244079694" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244079694">(Jun 27 2021 at 18:50)</a>:</h4>
<p>(although in this case it would be very easy to avoid using the stdlib, of course, so i have no <em>real</em> opposition to this function, although it will be annoying to change my old code that uses a trait for this if it's named <code>lerp</code>, since the inherent impl will override the trait-based implementation...)</p>



<a name="244079711"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244079711" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244079711">(Jun 27 2021 at 18:51)</a>:</h4>
<p><span class="user-mention silent" data-user-id="132829">Christopher Durham</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244078195">said</a>:</p>
<blockquote>
<p>I definitely agree that we'd want to use loose math that can optimize to FMA rather than requiring FMA</p>
</blockquote>
<p>By "loose math" do you mean something like GCC's -ffast-math? That's a bit of a can of worms, but in the past people have resisted the idea of adding such a flag to Rust and instead favored having different functions entirely for inexact math. For example, I could imagine a <code>lerp</code> function with all the correctness guarantees, and a <code>lerp_inexact</code> function for the screaming fast version.</p>



<a name="244079717"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244079717" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mara <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244079717">(Jun 27 2021 at 18:51)</a>:</h4>
<p><span class="user-mention silent" data-user-id="281757">Jubilee</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244079618">said</a>:</p>
<blockquote>
<p>are there consumers of this aside from gamedevs?</p>
</blockquote>
<p>i'd use it in control engineering. sensor fusion. flight controllers.</p>



<a name="244079782"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244079782" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244079782">(Jun 27 2021 at 18:52)</a>:</h4>
<blockquote>
<p>By "loose math" do you mean something like GCC's -ffast-math? That's a bit of a can of worms</p>
</blockquote>
<p>i have a WIP RFC for fast math (rather, more principled float model support), but i need to get back to it. it's certainly nontrivial</p>



<a name="244079799"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244079799" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244079799">(Jun 27 2021 at 18:52)</a>:</h4>
<p><span class="user-mention silent" data-user-id="256342">bstrie</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244079711">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="132829">Christopher Durham</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244078195">said</a>:</p>
<blockquote>
<p>I definitely agree that we'd want to use loose math that can optimize to FMA rather than requiring FMA</p>
</blockquote>
<p>By "loose math" do you mean something like GCC's -ffast-math? That's a bit of a can of worms, but in the past people have resisted the idea of adding such a flag to Rust and instead favored having different functions entirely for inexact math. For example, I could imagine a <code>lerp</code> function with all the correctness guarantees, and a <code>lerp_inexact</code> function for the screaming fast version.</p>
</blockquote>
<p>There's some discussion elsewhere on <em>targetted</em> use of inexact math, but a global <code>-ffast-math</code> isn't what I'm talking about. I'm just suggesting that <code>lerp</code> could be implemented with the float operations tagged with <code>contract</code> (or whatever the flag is) to <em>only</em> allow the increased-precision optimizations (i.e. FMA).</p>



<a name="244079823"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244079823" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244079823">(Jun 27 2021 at 18:53)</a>:</h4>
<p>i think llvm already has an intrinsic for "fma if hardware supported, separate mul+add otherwise"</p>



<a name="244079878"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244079878" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244079878">(Jun 27 2021 at 18:54)</a>:</h4>
<p>yeah, we'd just want to use <a href="https://llvm.org/docs/LangRef.html#llvm-fmuladd-intrinsic">https://llvm.org/docs/LangRef.html#llvm-fmuladd-intrinsic</a>, no need to worry about the contract optimization</p>



<a name="244079891"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244079891" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244079891">(Jun 27 2021 at 18:54)</a>:</h4>
<p>it would have to be implemented for cranelift/gcc, but ofc its fine to implement that as unfused</p>



<a name="244079915"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244079915" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244079915">(Jun 27 2021 at 18:55)</a>:</h4>
<p>But then again... gamedev is a field that does want to be able to get float determinism (for e.g. networking and replays), so perhaps baking in nondeterminism into a core primitive is just another way to make it not get used (in such use cases)...</p>



<a name="244079966"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244079966" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244079966">(Jun 27 2021 at 18:56)</a>:</h4>
<p>yeah, i think it would be fine to never fuse these operations, and then if we do get the ability to enable non-conforming float opttimizations, enabling contraction would improve the performance there</p>



<a name="244079996"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244079996" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244079996">(Jun 27 2021 at 18:57)</a>:</h4>
<p>The sad(ish) thing is that more precise FMA makes guaranteeing properties about <code>lerp</code> easier, so not using it means either less guarantees or more code</p>



<a name="244080044"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244080044" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244080044">(Jun 27 2021 at 18:58)</a>:</h4>
<p><span class="user-mention silent" data-user-id="310399">Mara</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244079717">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="281757">Jubilee</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244079618">said</a>:</p>
<blockquote>
<p>are there consumers of this aside from gamedevs?</p>
</blockquote>
<p>i'd use it in control engineering. sensor fusion. flight controllers.</p>
</blockquote>
<p>alright, it sounds like performance would still be a concern but correctness would tend to rate higher.</p>



<a name="244080272"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244080272" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244080272">(Jun 27 2021 at 19:04)</a>:</h4>
<p>All implementations seem to struggle most when numbers are (close to) denormal</p>



<a name="244080277"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244080277" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mara <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244080277">(Jun 27 2021 at 19:05)</a>:</h4>
<p><span class="user-mention silent" data-user-id="281757">Jubilee</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244080044">said</a>:</p>
<blockquote>
<p>alright, it sounds like performance would still be a concern but correctness would tend to rate higher.</p>
</blockquote>
<p>it'd probably be fine if things like this aren't perfect and a lsb or two off. but i rather pay a few extra clockcycles than potentially having to debug some issue with it. especially because instead of resulting in a flickering pixel, it might cause a heavy drone to fall out of the sky ^^</p>



<a name="244080283"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244080283" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244080283">(Jun 27 2021 at 19:05)</a>:</h4>
<p>Doing tests, <code>lerp(t, 0.06256735, 0.3860399)</code> gave me several steps of 2 ULP with <code>((1.0 - t) * v0) + (t * v1)</code></p>



<a name="244080290"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244080290" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244080290">(Jun 27 2021 at 19:05)</a>:</h4>
<p>I'm not qualified to do an analysis on the maximum ULP deviation from the perfect result though</p>



<a name="244080295"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244080295" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244080295">(Jun 27 2021 at 19:06)</a>:</h4>
<p>right, I think we can compromise on correctness here with a Good Enough at some point.</p>



<a name="244080343"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244080343" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244080343">(Jun 27 2021 at 19:06)</a>:</h4>
<p>I've not seen anything in my test range (of only doing numbers 0-1) that ever steps more than 2 ULP for a 1 ULP movement in t, though</p>



<a name="244080438"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244080438" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mara <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244080438">(Jun 27 2021 at 19:09)</a>:</h4>
<p><span class="user-mention silent" data-user-id="132829">Christopher Durham</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244079262">said</a>:</p>
<blockquote>
<p>I continue to wish that C++ papers included any of the motivation, but here's the paper that added <code>std::midpoint</code> and <code>std::lerp</code>: <a href="https://wg21.link/p0811">https://wg21.link/p0811</a></p>
</blockquote>
<p>i don't see any discussion about motivation or performance in the meeting notes either. :(</p>



<a name="244080485"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244080485" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244080485">(Jun 27 2021 at 19:10)</a>:</h4>
<p>feels like a bit of a "because it's there" at this point yeah.</p>



<a name="244081222"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244081222" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244081222">(Jun 27 2021 at 19:31)</a>:</h4>
<p>I made a math.SE question about showing a bound on the non-monoticity of <code>((1.0 - t) * v0) + (t * v1)</code>, but I don't really expect it to get any attention.<br>
<a href="https://math.stackexchange.com/q/4184626/573727">https://math.stackexchange.com/q/4184626/573727</a></p>



<a name="244081275"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244081275" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244081275">(Jun 27 2021 at 19:32)</a>:</h4>
<p>A previous math.SE, cited by P0811, which discusses providing guarantees as well: <a href="https://math.stackexchange.com/q/907327/573727">https://math.stackexchange.com/q/907327/573727</a></p>



<a name="244082968"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244082968" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Clar Fon <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244082968">(Jun 27 2021 at 20:19)</a>:</h4>
<p>wait, does <code>mul_add</code> in LLVM genuinely not just emit fma instructions on x86 and ARM? that was part of the main reason why I chose that implementation -- it's only two float instructions but gives you all the extra nice stuff for free</p>



<a name="244083207"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244083207" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244083207">(Jun 27 2021 at 20:25)</a>:</h4>
<p>I'd argue that <code>lerp</code> should be implemented as exactly <code>a * (1.0 - t) + b * t</code> since that version gives the endpoints for <code>t == 0.0 || t == 1.0</code>, it is 100% reproducible across all IEEE 754 compliant archs, I've also done some game-dev and am currently working on project-portable-simd as well as writing a Vulkan driver (Kazan) for Libre-SOC's CPU/GPU-hybrid that I'm also working on -- that formula avoids the biggest pitfall (not returning endpoints for <code>t == 1.0</code>) and is fast enough, it's also the same way linear bezier curves are implemented (we can argue about whether to spell <code>lerp</code> as <code>t.bezier([a, b])</code> and have <code>fn bezier&lt;const N: usize&gt;(self, control_points: [T; N]) -&gt; Self::Output</code> for all <code>N &gt; 0</code>, if we do, I think we should use a trait in order to allow (excuse my syntax) <code>f32::bezier([f32x4; 2]) -&gt; f32x4</code> and <code>f32x4::bezier([f32; 2]) -&gt; f32x4</code>).</p>



<a name="244083256"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244083256" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244083256">(Jun 27 2021 at 20:27)</a>:</h4>
<p><span class="user-mention silent" data-user-id="330161">Clar Fon</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244082968">said</a>:</p>
<blockquote>
<p>wait, does <code>mul_add</code> in LLVM genuinely not just emit fma instructions on x86 and ARM? that was part of the main reason why I chose that implementation -- it's only two float instructions but gives you all the extra nice stuff for free</p>
</blockquote>
<p>it does, but only when the <code>fma</code> target features are enabled -- otherwise it calls the <code>fma</code> math lib function.</p>



<a name="244083317"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244083317" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244083317">(Jun 27 2021 at 20:28)</a>:</h4>
<p>assuming you're referring to <code>f32::mul_add</code></p>



<a name="244083379"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244083379" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244083379">(Jun 27 2021 at 20:30)</a>:</h4>
<p>if your referring to <code>llvm.mul_add.*</code>, yes it is defined to generate,  depending on target support, either a separate mul and add or a fma -- no other options (without fast-math).</p>



<a name="244083672"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244083672" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Clar Fon <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244083672">(Jun 27 2021 at 20:38)</a>:</h4>
<p>I guess I should probably clarify where the FMA implementation came from -- I wrote up some code (which I unfortunately don't have right now, since my hard drive died) that would run some tests for the various different properties, with the goal of seeing what would be the most reasonable implementation with the least number of branches. I found that the FMA implementation had the least number of branches and the most guarantees, which is why I went with it. The <code>a * (1.0 - t) + b * t</code> was the runner-up but it took more operations, which is why I didn't go with it.</p>
<p>I was under the impression that nowdays basically every x86_64 and aarch64 processor supports FMA, and that LLVM would emit these instructions, which is why I assumed it would be fine. If that's not the case, then it's definitely worth reconsidering, since it can be more expensive than the alternatives.</p>



<a name="244083768"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244083768" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Clar Fon <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244083768">(Jun 27 2021 at 20:40)</a>:</h4>
<p>I also did some investigation into other lerp implementations (admittedly, not very much) and found that basically which version of the equation was used was almost entirely random, and I had assumed that most people hadn't given it much thought, which is why I went ahead with the FMA version. It was pretty consistent that most implementations chose to reduce the amount of branches, though (with the exception of those that explicitly wanted to clamp t to [0.0, 1.0]) and that C++ went overboard with around 5 branches per call.</p>



<a name="244083776"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244083776" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244083776">(Jun 27 2021 at 20:40)</a>:</h4>
<p>You can configure your Rust program to strictly require <code>fma</code>, but by default they do not have <code>fma</code> enabled as a required CPU ability, and so LLBM will not emit <code>fma</code> operaions</p>



<a name="244083882"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244083882" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Clar Fon <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244083882">(Jun 27 2021 at 20:42)</a>:</h4>
<p>I'm not knowledgeable enough about what hardware is out there, but it seems reasonable to assume that it'd take a lot of effort to find a CPU without FMA support nowadays, right? I would assume that most game, etc. software now tries to use it wherever they can, but I could be wrong about that.</p>



<a name="244083965"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244083965" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244083965">(Jun 27 2021 at 20:44)</a>:</h4>
<p>Currently, Rust only enables the minimum possible CPU features: <code>sse</code> and <code>sse2</code> on most x86_64, but also I <em>think</em> <code>ssse3</code> on one of the mac targets.</p>



<a name="244084686"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244084686" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Clar Fon <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244084686">(Jun 27 2021 at 21:01)</a>:</h4>
<p>okay, so, even with target-feature=fma, it seems that Rust still emits the libc instruction? o.o <a href="https://rust.godbolt.org/z/hWjsbxG9Y">https://rust.godbolt.org/z/hWjsbxG9Y</a></p>



<a name="244084802"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244084802" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244084802">(Jun 27 2021 at 21:03)</a>:</h4>
<p><span class="user-mention silent" data-user-id="330161">Clar Fon</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244083882">said</a>:</p>
<blockquote>
<p>I'm not knowledgeable enough about what hardware is out there, but it seems reasonable to assume that it'd take a lot of effort to find a CPU without FMA support nowadays, right? I would assume that most game, etc. software now tries to use it wherever they can, but I could be wrong about that.</p>
</blockquote>
<p>My laptop doesn't have FMA, it's a Intel Ivy Bridge microarchitecture (released 2013 according to Wikipedia).</p>



<a name="244084848"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244084848" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244084848">(Jun 27 2021 at 21:04)</a>:</h4>
<p><span class="user-mention silent" data-user-id="330161">Clar Fon</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244084686">said</a>:</p>
<blockquote>
<p>okay, so, even with target-feature=fma, it seems that Rust still emits the libc instruction? o.o <a href="https://rust.godbolt.org/z/hWjsbxG9Y">https://rust.godbolt.org/z/hWjsbxG9Y</a></p>
</blockquote>
<p>you'd have to build-std, which you can't do in godbolt currently</p>



<a name="244084855"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244084855" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244084855">(Jun 27 2021 at 21:05)</a>:</h4>
<p>admittedly I don't use my laptop much -- why I haven't upgraded.</p>



<a name="244084917"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244084917" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244084917">(Jun 27 2021 at 21:06)</a>:</h4>
<p>Does the Win11 minspec include FMA? I don't know what features are guaranteed by what.</p>



<a name="244084962"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244084962" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244084962">(Jun 27 2021 at 21:06)</a>:</h4>
<p>"basically yeah" since you need TPM 2.0 (i think technically 1.2 works also), which is new enough that you'll have FMA</p>



<a name="244084971"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244084971" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Clar Fon <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244084971">(Jun 27 2021 at 21:07)</a>:</h4>
<p><span class="user-mention silent" data-user-id="224471">Lokathor</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244084848">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="330161">Clar Fon</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244084686">said</a>:</p>
<blockquote>
<p>okay, so, even with target-feature=fma, it seems that Rust still emits the libc instruction? o.o <a href="https://rust.godbolt.org/z/hWjsbxG9Y">https://rust.godbolt.org/z/hWjsbxG9Y</a></p>
</blockquote>
<p>you'd have to build-std, which you can't do in godbolt currently</p>
</blockquote>
<p>isn't the function marked as inline, though? I didn't realise that you had to call the intrinsic directly for it to be optimised</p>



<a name="244084973"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244084973" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244084973">(Jun 27 2021 at 21:07)</a>:</h4>
<p><span class="user-mention silent" data-user-id="260325">Chris Denton</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244084959">said</a>:</p>
<blockquote>
<p>Try <code>-O -C target-cpu=native</code>?</p>
</blockquote>
<p>oh, right, you didn't set <code>-Copt-level=3</code></p>



<a name="244084979"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244084979" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244084979">(Jun 27 2021 at 21:07)</a>:</h4>
<p><span class="user-mention silent" data-user-id="330161">Clar Fon</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244084686">said</a>:</p>
<blockquote>
<p>okay, so, even with target-feature=fma, it seems that Rust still emits the libc instruction? o.o <a href="https://rust.godbolt.org/z/hWjsbxG9Y">https://rust.godbolt.org/z/hWjsbxG9Y</a></p>
</blockquote>
<p>You have to use <code>-C target-feature=+fma</code>, not <code>-C target-feature=fma</code></p>



<a name="244085039"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085039" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Clar Fon <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085039">(Jun 27 2021 at 21:08)</a>:</h4>
<p>ah, I see now. this works, then: <a href="https://rust.godbolt.org/z/EdeEd6n74">https://rust.godbolt.org/z/EdeEd6n74</a></p>



<a name="244085042"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085042" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085042">(Jun 27 2021 at 21:08)</a>:</h4>
<p><code>-O -C target-feature=fma -C target-cpu=skylake</code> gives you a <code>jmp</code>, <code>-O -C target-feature=+fma -C target-cpu=skylake</code> gives you a <code>vfmadd213sd</code></p>



<a name="244085052"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085052" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085052">(Jun 27 2021 at 21:09)</a>:</h4>
<p>rustc definitely should probably at least warn on <code>-C target-feature=feat</code> instead of <code>-C target-feature=+feat</code> or <code>-C target-feature=-feat</code></p>



<a name="244085062"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085062" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085062">(Jun 27 2021 at 21:09)</a>:</h4>
<p><code>-feat</code> <em>should</em> work (though perhaps it doesn't)</p>



<a name="244085069"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085069" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Clar Fon <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085069">(Jun 27 2021 at 21:09)</a>:</h4>
<p>Still, I think that the takeaway is that unfortunately, even in the year 2021, we can't rely on FMA being emitted or supported by CPUs, meaning that FMA doesn't have the benefit of only emitting one instruction</p>



<a name="244085112"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085112" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085112">(Jun 27 2021 at 21:10)</a>:</h4>
<p>Current behavior on godbolt seems to be <code>=feat</code> disables, <code>=-feat</code> disables, <code>=+feat</code> enables</p>



<a name="244085142"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085142" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085142">(Jun 27 2021 at 21:11)</a>:</h4>
<p><span class="user-mention silent" data-user-id="310399">Mara</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244080277">said</a>:</p>
<blockquote>
<p>especially because instead of resulting in a flickering pixel, it might cause a heavy drone to fall out of the sky ^^</p>
</blockquote>
<p>well, it is worth noting that floating point inaccuracy in some computational geometry function (for example, in collision detection) can be the difference between a function that converges and one that infinite loops¹, so it's not <em>all</em> just about graphical errors — it can also cause serious bugs for us too if stuff is dubious.</p>
<p>that said, for code that sensitive you often prefer to avoid library functions that you don't control, unless they are precisely specified (for that reason).</p>
<p>¹ okay, in practice you usually put a bound of ~100 or so on this, with a debug_assert that it never reaches that</p>
<p><span class="user-mention silent" data-user-id="229517">Jacob Lifshay</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244083207">said</a>:</p>
<blockquote>
<p>I'd argue that <code>lerp</code> should be implemented as exactly <code>a * (1.0 - t) + b * t</code> since that version gives the endpoints for <code>t == 0.0 || t == 1.0</code>, it is 100% reproducible across all IEEE 754 compliant archs...</p>
</blockquote>
<p>fwiw this is simple enough to be completely usable in games, and i agree that it avoids most of the pitfalls, including determinism/platform independence, returning correct results on the endpoints, etc. i can't really say how important the guarantees are for other disciplines tho</p>



<a name="244085200"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085200" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Clar Fon <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085200">(Jun 27 2021 at 21:13)</a>:</h4>
<p>in slightly more positive news, aarch64 does guarantee fma instructions by itself, unlike x86: <a href="https://rust.godbolt.org/z/cE1K8oaGc">https://rust.godbolt.org/z/cE1K8oaGc</a></p>



<a name="244085257"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085257" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085257">(Jun 27 2021 at 21:14)</a>:</h4>
<p>The one thing keeping me from saying just go with <code>(1.0 - t) * v0 + t * v1</code> is the fact (fear?) that it can return values outside of <code>v0..=v1</code> even when <code>t</code> is in <code>0..=1</code></p>



<a name="244085282"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085282" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085282">(Jun 27 2021 at 21:15)</a>:</h4>
<p>If we could confidently determine that that isn't the case, and/or put a confidence on the ULP variance, then I'd 100% say just use that impl</p>



<a name="244085297"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085297" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085297">(Jun 27 2021 at 21:15)</a>:</h4>
<p>But at the same time, this thread was initially supposed to be for the API, not the implementation <span aria-label="upside down" class="emoji emoji-1f643" role="img" title="upside down">:upside_down:</span></p>



<a name="244085356"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085356" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Clar Fon <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085356">(Jun 27 2021 at 21:17)</a>:</h4>
<p>apologies for commandeering the thread <span aria-label="frown" class="emoji emoji-1f641" role="img" title="frown">:frown:</span></p>
<p>I do think that both aspects are important, though</p>



<a name="244085362"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085362" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085362">(Jun 27 2021 at 21:17)</a>:</h4>
<p>well the "good" implementation is clearly <code>lerp&lt;F: CanLerp&gt;(start: F, end: F, percent: F) -&gt; F</code> ;P</p>



<a name="244085422"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085422" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Clar Fon <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085422">(Jun 27 2021 at 21:18)</a>:</h4>
<p>ignoring the joke, I do think that the standard library's current status quo forbids making <code>lerp</code> part of a trait, and would delegate that to crates like <code>num-traits</code></p>



<a name="244085441"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085441" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085441">(Jun 27 2021 at 21:18)</a>:</h4>
<p><span class="user-mention silent" data-user-id="224471">Lokathor</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244085362">said</a>:</p>
<blockquote>
<p>well the "good" implementation is clearly <code>lerp&lt;F: CanLerp&gt;(start: F, end: F, percent: F) -&gt; F</code> ;P</p>
</blockquote>
<p>Not quite, see e.g. <a href="https://docs.rs/ultraviolet/0.8.1/ultraviolet/interp/trait.Lerp.html">ultraviolet's definition of <code>Lerp</code></a></p>



<a name="244085455"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085455" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085455">(Jun 27 2021 at 21:19)</a>:</h4>
<p>If you have that trait you can make the free function, so, sure</p>



<a name="244085480"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085480" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085480">(Jun 27 2021 at 21:20)</a>:</h4>
<p>I'm talking about the fact that you can lerp with a different type for the t than the interpolated value</p>



<a name="244085517"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085517" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085517">(Jun 27 2021 at 21:20)</a>:</h4>
<p>Anyway, I would like to avoid providing a std lerp signature which 3rd party crates cannot use, separately from the "what are they already using" question</p>



<a name="244085538"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085538" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085538">(Jun 27 2021 at 21:20)</a>:</h4>
<p>It would be bad imo if std uses <code>t.lerp(v0, v1)</code> but 3rd party crates <em>have</em> to continue to use <code>v0.lerp(v1, t)</code> because they cannot use <code>t.lerp(v0, v1)</code> and match std</p>



<a name="244085554"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085554" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Clar Fon <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085554">(Jun 27 2021 at 21:21)</a>:</h4>
<p>strongly agree. the end result has to be one of the two changing, and for the moment it's swinging heavily in the favor of changing the libstd lerp, despite what I would prefer</p>



<a name="244085557"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085557" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085557">(Jun 27 2021 at 21:21)</a>:</h4>
<p>that would be worse than Ranges not being Copy</p>



<a name="244085608"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085608" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085608">(Jun 27 2021 at 21:22)</a>:</h4>
<p>The thing is that 3rd party libs can't even define <code>f32::lerp(self, v0: Vec3, v1: Vec3)</code> if we provide an inherent <code>lerp</code> that's not generic</p>



<a name="244085621"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085621" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085621">(Jun 27 2021 at 21:23)</a>:</h4>
<p>Well, if we spell it <code>t.bezier([a, b])</code> we don't have to worry about conflicting with the many differing <code>lerp</code> signatures.</p>



<a name="244085642"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085642" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085642">(Jun 27 2021 at 21:23)</a>:</h4>
<p>i dont think there's a good way to make it part of a trait really. even the suggestion in the thread for the <code>Lerp</code> trait has the issue that it locks us into having f64 as the highest precision floats (and regardless of your feelings here — i personally suspect there are more reasons not to support any form of extended precision than there are to support them — we probably don't want to do that for something like this)</p>



<a name="244085697"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085697" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085697">(Jun 27 2021 at 21:24)</a>:</h4>
<p>not if it's Lerp&lt;T&gt;</p>



<a name="244085700"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085700" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Clar Fon <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085700">(Jun 27 2021 at 21:24)</a>:</h4>
<p>yeah, I strongly disagree with locking any particular float type. and am against <code>bezier</code> as a name, as it's explicitly linear interpolation</p>



<a name="244085702"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085702" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085702">(Jun 27 2021 at 21:24)</a>:</h4>
<p>The alternative to my hardcoded dispatch to <code>f32</code> and <code>f64</code> is to make it MORE GENERIC with <code>Lerp&lt;T&gt;</code></p>



<a name="244085709"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085709" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085709">(Jun 27 2021 at 21:24)</a>:</h4>
<p>Again, see ultraviolet as an example <a href="https://docs.rs/ultraviolet/0.8.1/ultraviolet/interp/trait.Lerp.html">https://docs.rs/ultraviolet/0.8.1/ultraviolet/interp/trait.Lerp.html</a></p>



<a name="244085725"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085725" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085725">(Jun 27 2021 at 21:25)</a>:</h4>
<p>Though that's <code>v0.lerp(v1, t)</code>, it could potentially be jiggled into <code>t.lerp(v0, v1)</code> order...</p>



<a name="244085795"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085795" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085795">(Jun 27 2021 at 21:26)</a>:</h4>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">trait</span><span class="w"> </span><span class="n">Bezier</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="n">N</span>: <span class="kt">usize</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">type</span> <span class="nc">Output</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="k">fn</span> <span class="nf">bezier</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">control_points</span>: <span class="p">[</span><span class="n">T</span><span class="p">;</span><span class="w"> </span><span class="n">N</span><span class="p">])</span><span class="w"> </span>-&gt; <span class="nc">Self</span>::<span class="n">Output</span><span class="p">;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="244085806"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085806" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Clar Fon <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085806">(Jun 27 2021 at 21:27)</a>:</h4>
<p>a full bézier implementation is much more nuanced than linear interpolation, though. it's way less used than lerp.</p>



<a name="244085820"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085820" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085820">(Jun 27 2021 at 21:27)</a>:</h4>
<p><span class="user-mention silent" data-user-id="330161">Clar Fon</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244085806">said</a>:</p>
<blockquote>
<p>a full bézier implementation is much more nuanced than linear interpolation, though. it's way less used than lerp.</p>
</blockquote>
<p>While it's less used, it's not really more nuanced. It's just a lerp of lerps.</p>



<a name="244085822"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085822" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085822">(Jun 27 2021 at 21:27)</a>:</h4>
<p><span class="user-mention silent" data-user-id="330161">Clar Fon</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244085554">said</a>:</p>
<blockquote>
<p>strongly agree. the end result has to be one of the two changing, and for the moment it's swinging heavily in the favor of changing the libstd lerp, despite what I would prefer</p>
</blockquote>
<p>I think this is a bit extreme. If there's truly a worry with clashing with library crates, then I'd pick a name other than <code>lerp</code> rather than contort the function signature.</p>



<a name="244085823"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085823" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085823">(Jun 27 2021 at 21:27)</a>:</h4>
<p><span class="user-mention silent" data-user-id="330161">Clar Fon</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244085700">said</a>:</p>
<blockquote>
<p>yeah, I strongly disagree with locking any particular float type. and am against <code>bezier</code> as a name, as it's explicitly linear interpolation</p>
</blockquote>
<p>but a second-order Bezier Curve is explicitly linear interpolation...</p>



<a name="244085884"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085884" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Clar Fon <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085884">(Jun 27 2021 at 21:29)</a>:</h4>
<p>how do you define a 0th-order or 1st-order bézier, though? and what level of accuracy do you guarantee?</p>



<a name="244085885"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085885" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085885">(Jun 27 2021 at 21:29)</a>:</h4>
<p>in particular I think it would be very unprecedented for the stdlib to condone splitting the endpoints of a range across the receiver and the arguments</p>



<a name="244085956"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085956" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085956">(Jun 27 2021 at 21:30)</a>:</h4>
<p><span class="user-mention silent" data-user-id="330161">Clar Fon</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244085884">said</a>:</p>
<blockquote>
<p>how do you define a 0th-order or 1st-order bézier, though? and what level of accuracy do you guarantee?</p>
</blockquote>
<p>It'd have to be in the <strong><em>future</em></strong> of const generics where you could exclude <code>0</code>. A 1st order is just returning the argument.</p>



<a name="244085971"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085971" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085971">(Jun 27 2021 at 21:30)</a>:</h4>
<p>we <em>can</em> get away with just implementing 2nd, 3rd, and 4th order Bezier curves for now, and leave the fully general implementation for later. the <code>Bezier</code> trait can still be generic over <code>N</code>, we just have std impls for <code>N == 2, 3, 4</code></p>



<a name="244085993"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244085993" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244085993">(Jun 27 2021 at 21:31)</a>:</h4>
<p>speaking as a pure outsider here, "lerp" feels like forbidding jargon that means nothing to anyone who doesn't already know what it means. "bezier" is only mildly better.</p>



<a name="244086075"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086075" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086075">(Jun 27 2021 at 21:32)</a>:</h4>
<p>which is not to imply that I really care strongly about bikeshedding the name of this API, but if a problem can be solved by renaming, I'm just saying that the current name is not exactly ideal</p>



<a name="244086076"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086076" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086076">(Jun 27 2021 at 21:32)</a>:</h4>
<p>how about having doc aliases for <code>lerp</code> and <code>interpolate</code> on <code>bezier</code>?</p>



<a name="244086091"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086091" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Clar Fon <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086091">(Jun 27 2021 at 21:33)</a>:</h4>
<p>doc aliases could solve the issue, although again, I'm not sure that it's a good precedent to have a full bézier implementation in libstd</p>



<a name="244086092"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086092" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086092">(Jun 27 2021 at 21:33)</a>:</h4>
<p>why not "interpolate"?</p>



<a name="244086097"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086097" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086097">(Jun 27 2021 at 21:33)</a>:</h4>
<p>i think that even if bezier is a thing, lerp will also be a thing, because that's more what people expect</p>



<a name="244086102"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086102" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086102">(Jun 27 2021 at 21:33)</a>:</h4>
<p><span class="user-mention silent" data-user-id="256342">bstrie</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244085993">said</a>:</p>
<blockquote>
<p>speaking as a pure outsider here, "lerp" feels like forbidding jargon that means nothing to anyone who doesn't already know what it means. "bezier" is only mildly better.</p>
</blockquote>
<p>My response to that, unfortunately, is "well what is <code>cmp</code>, <code>str</code>, <code>fn</code>, <code>rc</code>, <code>mutex</code>?" <code>lerp</code> is the industry standard name for the function.</p>



<a name="244086107"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086107" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086107">(Jun 27 2021 at 21:34)</a>:</h4>
<p>but, I could write a full bezier implementation for <code>f32</code> in &lt;20loc...</p>



<a name="244086146"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086146" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086146">(Jun 27 2021 at 21:34)</a>:</h4>
<p>sure, but a lot of those names are also awful, and <em>somebody</em> has to be grumpy about it :P don't get me started on "string"...</p>



<a name="244086157"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086157" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086157">(Jun 27 2021 at 21:34)</a>:</h4>
<p>pub struct ListOfUnicodeCodePoints { ... }</p>



<a name="244086171"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086171" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086171">(Jun 27 2021 at 21:34)</a>:</h4>
<p>try <code>Text</code> :P</p>



<a name="244086178"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086178" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Clar Fon <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086178">(Jun 27 2021 at 21:35)</a>:</h4>
<p>sure, you could easily write a bézier implementation, and you could easily write a gamma and zeta implementation, and--</p>



<a name="244086179"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086179" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086179">(Jun 27 2021 at 21:35)</a>:</h4>
<p>but I digress</p>



<a name="244086187"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086187" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086187">(Jun 27 2021 at 21:35)</a>:</h4>
<p>better would be <code>struct TextBuf</code> and <code>text</code></p>



<a name="244086199"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086199" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Clar Fon <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086199">(Jun 27 2021 at 21:35)</a>:</h4>
<p>I feel like regardless of what happens, the discussion should be on how lerp should work, not whether we should have a full bézier implementation instead</p>



<a name="244086243"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086243" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086243">(Jun 27 2021 at 21:36)</a>:</h4>
<p>it would take waay more code to get a good <code>gamma</code> or <code>zeta</code> implementation, bezier is relatively simple by comparison.</p>



<a name="244086246"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086246" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086246">(Jun 27 2021 at 21:36)</a>:</h4>
<p><span class="user-mention" data-user-id="330161">@Clar Fon</span> I think that "core and std can't have nice things" is a poor stance that the rust project often accidentally leans towards. If we can provide good things, particularly low maintenance ones, we should.</p>



<a name="244086259"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086259" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Clar Fon <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086259">(Jun 27 2021 at 21:37)</a>:</h4>
<p>that's very fair, Lokathor</p>



<a name="244086266"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086266" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Clar Fon <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086266">(Jun 27 2021 at 21:37)</a>:</h4>
<p>and I shouldn't be using the slippery slope argument</p>



<a name="244086268"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086268" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Clar Fon <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086268">(Jun 27 2021 at 21:37)</a>:</h4>
<p>my main concern is that making a good API for bézier is trickier than lerp</p>



<a name="244086273"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086273" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086273">(Jun 27 2021 at 21:37)</a>:</h4>
<p>now that's valid. If the API is hard to design that's a true concern</p>



<a name="244086315"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086315" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086315">(Jun 27 2021 at 21:38)</a>:</h4>
<p><span class="user-mention silent" data-user-id="330161">Clar Fon</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244086268">said</a>:</p>
<blockquote>
<p>my main concern is that making a good API for bézier is trickier than lerp</p>
</blockquote>
<p>There's less question on whether <code>v0.bezier(v1, v2, t)</code> is valid, though <span aria-label="smile" class="emoji emoji-1f642" role="img" title="smile">:smile:</span> because it's clearly not</p>



<a name="244086320"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086320" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Clar Fon <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086320">(Jun 27 2021 at 21:38)</a>:</h4>
<p>agreed</p>



<a name="244086372"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086372" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086372">(Jun 27 2021 at 21:40)</a>:</h4>
<p>personally i'm not sure i'd be entirely comfortable with <code>bezier</code> being in my math code even if it gives identical results just because i'm a dummy that doesn't know math and so i'm not familiar with it. I'd genuinely like it to say the normal name "lerp" so that I know it's the normal thing.</p>



<a name="244086388"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086388" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Clar Fon <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086388">(Jun 27 2021 at 21:41)</a>:</h4>
<p>there is definitely comfort to be found in simple cases of larger things. it's why a lot of people have trouble with Haskell even though technically you can say that a lot of things are monoids</p>



<a name="244086434"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086434" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086434">(Jun 27 2021 at 21:42)</a>:</h4>
<p>As proof of simplicity, <code>Bezier</code> and <code>Lerp</code>-from-<code>Bezier</code>: <a href="https://play.rust-lang.org/?version=nightly&amp;mode=debug&amp;edition=2018&amp;gist=06be1bed6c1e6a0a68bd5fcf2f34bdc7">https://play.rust-lang.org/?version=nightly&amp;mode=debug&amp;edition=2018&amp;gist=06be1bed6c1e6a0a68bd5fcf2f34bdc7</a></p>



<a name="244086442"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086442" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086442">(Jun 27 2021 at 21:43)</a>:</h4>
<p>But also I can see how this is potentially too "clever" for std (whereas it'd be right at home in e.g. nalgebra)</p>



<a name="244086445"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086445" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086445">(Jun 27 2021 at 21:43)</a>:</h4>
<p><span class="user-mention silent" data-user-id="256342">bstrie</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244086171">said</a>:</p>
<blockquote>
<p>try <code>Text</code> :P</p>
</blockquote>
<p>Text is what a human reads and writes. Strings are not required to have such meaning. <span aria-label="innocent" class="emoji emoji-1f607" role="img" title="innocent">:innocent:</span></p>



<a name="244086492"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086492" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086492">(Jun 27 2021 at 21:44)</a>:</h4>
<p>And with more careful consideration of base impls (plus better const generics and specialization oh my) you could extend it so you can get everything when providing just <code>impl Bezier&lt;Scalar, 2&gt; for MyType</code>.</p>



<a name="244086552"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086552" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086552">(Jun 27 2021 at 21:46)</a>:</h4>
<p>I'd be happy to see the <code>Bezier</code>/<code>Lerp</code> in that playground in std, though I worry if this steps too much towards <code>num</code>, which was separated from <code>std</code> for a reason</p>



<a name="244086569"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086569" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086569">(Jun 27 2021 at 21:46)</a>:</h4>
<p>nor actually be rendered ( merely renderable )<br>
regardless, the virtues quickly err in favor of terseness for experienced users, and the real mistake is not in such but in going so overboard the code is unreadable.</p>



<a name="244086637"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086637" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086637">(Jun 27 2021 at 21:48)</a>:</h4>
<p>( e.g. "jnz" instead of "jump_nonzero", really? )</p>



<a name="244086659"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086659" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086659">(Jun 27 2021 at 21:49)</a>:</h4>
<p>can't believe you're not spelling it the obviously correct way: jn0</p>



<a name="244086666"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086666" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086666">(Jun 27 2021 at 21:49)</a>:</h4>
<p>As you <em>could</em> generically provide a single default <code>Bezier</code> impl for any <code>T, S</code> where <code>S: One + Sub&lt;Output=S&gt;, T: Add&lt;Output=Self&gt; + Mul&lt;S, Output=Self&gt;</code> (I think I got those bounds correct)</p>



<a name="244086683"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086683" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086683">(Jun 27 2021 at 21:49)</a>:</h4>
<p>I rest my case <span aria-label="grinning face with smiling eyes" class="emoji emoji-1f601" role="img" title="grinning face with smiling eyes">:grinning_face_with_smiling_eyes:</span></p>



<a name="244086736"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086736" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086736">(Jun 27 2021 at 21:50)</a>:</h4>
<p>So the problem with all the generics is that the docs become incomprehensible</p>



<a name="244086754"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086754" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086754">(Jun 27 2021 at 21:50)</a>:</h4>
<p>also num was split from std ages ago when we knew a lot less about rust, i think these days we know a lot more, and eventually we should bring num stuff back into core</p>



<a name="244086763"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244086763" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244086763">(Jun 27 2021 at 21:51)</a>:</h4>
<p><span class="user-mention silent" data-user-id="224471">Lokathor</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244086736">said</a>:</p>
<blockquote>
<p>So the problem with all the generics is that the docs become incomprehensible</p>
</blockquote>
<p>Agree, as another key point of gamedev libs that mainline libs tend to ignore is simplicity and low-optimization perf</p>



<a name="244087026"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244087026" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244087026">(Jun 27 2021 at 21:56)</a>:</h4>
<p>I'm sorry</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">impl</span><span class="o">&lt;</span><span class="n">S</span><span class="p">,</span><span class="w"> </span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="n">Bezier</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="o">&gt;</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">S</span><span class="w"></span>
<span class="k">where</span><span class="w"></span>
<span class="w">    </span><span class="n">S</span>: <span class="nc">One</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="k">for</span><span class="o">&lt;'</span><span class="na">a</span><span class="o">&gt;</span><span class="w"> </span><span class="o">&amp;'</span><span class="na">a</span><span class="w"> </span><span class="n">S</span>: <span class="nc">Sub</span><span class="o">&lt;</span><span class="n">Output</span><span class="o">=</span><span class="n">S</span><span class="o">&gt;</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="n">T</span>: <span class="nc">Add</span><span class="o">&lt;</span><span class="n">Output</span><span class="o">=</span><span class="n">T</span><span class="o">&gt;</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="k">for</span><span class="o">&lt;'</span><span class="na">a</span><span class="o">&gt;</span><span class="w"> </span><span class="o">&amp;'</span><span class="na">a</span><span class="w"> </span><span class="n">T</span>: <span class="nc">Mul</span><span class="o">&lt;&amp;'</span><span class="na">a</span><span class="w"> </span><span class="n">S</span><span class="p">,</span><span class="w"> </span><span class="n">Output</span><span class="o">=</span><span class="n">T</span><span class="o">&gt;</span><span class="p">,</span><span class="w"></span>
<span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">fn</span> <span class="nf">bezier</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="n">v0</span><span class="p">,</span><span class="w"> </span><span class="n">v1</span><span class="p">]</span>: <span class="kp">&amp;</span><span class="p">[</span><span class="n">T</span><span class="p">;</span><span class="w"> </span><span class="mi">2</span><span class="p">])</span><span class="w"> </span>-&gt; <span class="nc">T</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">v0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="o">&amp;</span><span class="p">(</span><span class="o">&amp;</span><span class="n">S</span>::<span class="n">one</span><span class="p">()</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="bp">self</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">v1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="bp">self</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="244087118"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244087118" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244087118">(Jun 27 2021 at 21:58)</a>:</h4>
<p>And to be clear I'm aware that it's probably better to be <code>splat(one())</code> rather than just <code>one()</code> but even I have a limit somewhere</p>



<a name="244087143"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244087143" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244087143">(Jun 27 2021 at 21:59)</a>:</h4>
<p>And it's that I don't see anyone provide a generic <code>splat</code> <span aria-label="laughing" class="emoji emoji-1f606" role="img" title="laughing">:laughing:</span></p>



<a name="244087197"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244087197" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244087197">(Jun 27 2021 at 22:00)</a>:</h4>
<p>splat!</p>



<a name="244087251"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244087251" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244087251">(Jun 27 2021 at 22:00)</a>:</h4>
<p>the subtlety of this API is getting to the point where I feel like an actual RFC might be in order</p>



<a name="244087267"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244087267" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244087267">(Jun 27 2021 at 22:01)</a>:</h4>
<p>I'm just tangenting onto <code>Bezier</code> because nerd catnip tbf</p>



<a name="244087270"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244087270" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244087270">(Jun 27 2021 at 22:01)</a>:</h4>
<p><span aria-label="upside down" class="emoji emoji-1f643" role="img" title="upside down">:upside_down:</span></p>



<a name="244087281"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244087281" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244087281">(Jun 27 2021 at 22:01)</a>:</h4>
<p>one last thing though: the definition of <code>Lerp</code> from an order-2 <code>Bezier</code> feels inverted to me</p>



<a name="244087413"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244087413" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244087413">(Jun 27 2021 at 22:04)</a>:</h4>
<p>Sure, pure linear interpolation <em>is</em> a special case of bezier interpolation, but... at least every time someone's explained bezier interpolation it's been by using lerps</p>



<a name="244088121"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244088121" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244088121">(Jun 27 2021 at 22:23)</a>:</h4>
<p>Full naive bezier implementation for any degree for <code>f32</code>: <a href="https://play.rust-lang.org/?version=stable&amp;mode=release&amp;edition=2018&amp;gist=5ed4f67104e633cc51708c8334769622">https://play.rust-lang.org/?version=stable&amp;mode=release&amp;edition=2018&amp;gist=5ed4f67104e633cc51708c8334769622</a></p>



<a name="244088198"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244088198" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244088198">(Jun 27 2021 at 22:25)</a>:</h4>
<p>if you look at the llvm ir for <code>lerp_test</code> which is implemented in terms of bezier, it's there just so it generates llvm ir, you can see it's identical to <code>(1.0 - t) * a +  t * b</code></p>



<a name="244088539"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244088539" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244088539">(Jun 27 2021 at 22:34)</a>:</h4>
<p>Well, I understand defining bezier as lerp-of-lerps, and don't really understand how you've implemented it here, so, uh, point against for simplicity. I have very little idea how I'd go about making e.g. a <code>Vec3</code> type work with this trait.</p>



<a name="244088550"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244088550" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244088550">(Jun 27 2021 at 22:35)</a>:</h4>
<p>I think the one thing we're relatively sure of is that whatever <code>lerp</code> stdlib gets (if it gets one) should be a signature also providable by 3rd party math libs for their own types</p>



<a name="244088600"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244088600" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244088600">(Jun 27 2021 at 22:36)</a>:</h4>
<p>portable simd will, for example, want to lerp as well</p>



<a name="244088605"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244088605" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244088605">(Jun 27 2021 at 22:36)</a>:</h4>
<p>(Loathe to say it, but, what about non-<code>Copy</code> numeric types...)</p>



<a name="244088616"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244088616" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244088616">(Jun 27 2021 at 22:37)</a>:</h4>
<p>That's not even unreasonable. A sufficiently large matrix might be Vec&lt;f32&gt; backed</p>



<a name="244088675"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244088675" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244088675">(Jun 27 2021 at 22:38)</a>:</h4>
<p>So I guess we'd want to do something like <code>Add</code> &amp; the other math traits where it's implemented both for <code>&amp;T</code> and <code>T</code> when <code>T: Copy</code>?</p>



<a name="244088686"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244088686" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244088686">(Jun 27 2021 at 22:39)</a>:</h4>
<p>Yeah, I think I'm agreeing now that there's enough nuance here that this should go through a proper RFC to get more eyes and discussion</p>



<a name="244088699"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244088699" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244088699">(Jun 27 2021 at 22:39)</a>:</h4>
<p>i think the type being lerped is always taken by self, and then you can clone it if you want to, otherwise you just update in place and return using the same heap allocation</p>



<a name="244088742"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244088742" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244088742">(Jun 27 2021 at 22:40)</a>:</h4>
<p>that is, the caller can decide if they want to do that clone, the impl will akways take by self and always modify in place</p>



<a name="244088743"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244088743" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244088743">(Jun 27 2021 at 22:40)</a>:</h4>
<p>Feels more like <code>lerp(&amp;mut self, v1, t)</code> now...</p>



<a name="244088752"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244088752" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244088752">(Jun 27 2021 at 22:41)</a>:</h4>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">pub</span><span class="w"> </span><span class="k">trait</span><span class="w"> </span><span class="n">Add</span><span class="o">&lt;</span><span class="n">Rhs</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="bp">Self</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">type</span> <span class="nc">Output</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="cp">#[must_use]</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">add</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">rhs</span>: <span class="nc">Rhs</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">Self</span>::<span class="n">Output</span><span class="p">;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="244088757"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244088757" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244088757">(Jun 27 2021 at 22:41)</a>:</h4>
<p>And <code>AddAssign</code> for inplace</p>



<a name="244088761"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244088761" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244088761">(Jun 27 2021 at 22:41)</a>:</h4>
<p>well, yeah, but you would unlikely have lerpassign</p>



<a name="244088809"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244088809" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244088809">(Jun 27 2021 at 22:42)</a>:</h4>
<p>So would this be <code>Lerp(self, v1: &amp;Self, t: &amp;Scale) -&gt; Self</code> then?</p>



<a name="244088818"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244088818" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244088818">(Jun 27 2021 at 22:43)</a>:</h4>
<p>v1 probably is also moved</p>



<a name="244088821"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244088821" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244088821">(Jun 27 2021 at 22:43)</a>:</h4>
<p>Lerp(self, v1: Self, t: Scale) -&gt; Self</p>



<a name="244088862"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244088862" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244088862">(Jun 27 2021 at 22:44)</a>:</h4>
<p>I will note that this has got us back to <code>v0.lerp(v1, t)</code></p>



<a name="244088866"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244088866" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244088866">(Jun 27 2021 at 22:44)</a>:</h4>
<p>no avoiding that</p>



<a name="244088894"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244088894" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244088894">(Jun 27 2021 at 22:45)</a>:</h4>
<p>well, if the trait takes both <code>t</code> and <code>control_points</code> by value, you <em>can</em> just implement it for <code>&amp;YourHeavyweightType</code></p>



<a name="244088950"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244088950" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244088950">(Jun 27 2021 at 22:47)</a>:</h4>
<p>I'm at the point where I've no more to add so I'm going to go do the work that I'm supposed to be doing right now /wave</p>



<a name="244088960"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244088960" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244088960">(Jun 27 2021 at 22:47)</a>:</h4>
<p>kinda like how <code>num_bigint::BigInt</code> impls <code>Add</code> for both references and by-value <code>BigInt</code></p>



<a name="244090349"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244090349" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244090349">(Jun 27 2021 at 23:27)</a>:</h4>
<p>I ran <a href="https://play.rust-lang.org/?version=stable&amp;mode=release&amp;edition=2018&amp;gist=20d7ed562c014947fa1d21631f69de9f">some code</a> that suggests that <code>((1.0 - t) * v0) + (t * v1)</code> is in fact <strong><em>bounded</em></strong> to return a value between <code>v0</code> and <code>v1</code>. I still feel like I've seen a counterexample at some point, but perhaps I'm mistaken.</p>



<a name="244090414"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244090414" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244090414">(Jun 27 2021 at 23:29)</a>:</h4>
<p>... and nvm adjusted it and found a counterexample quickly: <code>lerp(0.000000029802326, 139443040, 197225040) = 139443020</code></p>



<a name="244090965"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244090965" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244090965">(Jun 27 2021 at 23:45)</a>:</h4>
<p>(That's 1 ULP out of range)</p>



<a name="244091031"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244091031" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244091031">(Jun 27 2021 at 23:47)</a>:</h4>
<p>Adjusted code: <a href="https://play.rust-lang.org/?version=stable&amp;mode=release&amp;edition=2018&amp;gist=8c98a6c4ebd605b374a9566db74dc328">https://play.rust-lang.org/?version=stable&amp;mode=release&amp;edition=2018&amp;gist=8c98a6c4ebd605b374a9566db74dc328</a></p>



<a name="244091929"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244091929" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244091929">(Jun 28 2021 at 00:13)</a>:</h4>
<p>So what's the biggest start/end range where 0.0 ..= 1.0 for scale will always give correctly start ..= end</p>



<a name="244091974"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244091974" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244091974">(Jun 28 2021 at 00:14)</a>:</h4>
<p>like, if it's "something big" then can we note that in the docs and say "you only need to worry if inputs exceed +/- FOONUM"</p>



<a name="244093091"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244093091" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244093091">(Jun 28 2021 at 00:48)</a>:</h4>
<p>It's worth noting that it's monotonic if the signs of <code>v0</code> and <code>v1</code> differ</p>



<a name="244093097"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244093097" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244093097">(Jun 28 2021 at 00:48)</a>:</h4>
<p>So technically, an arbitrarily large range could be monotonic</p>



<a name="244093108"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244093108" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244093108">(Jun 28 2021 at 00:49)</a>:</h4>
<p>I don't know an efficient way to search for the smallest input where it lacks <strong><em>boundedness</em></strong> though</p>



<a name="244093324"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244093324" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244093324">(Jun 28 2021 at 00:55)</a>:</h4>
<p>Well i'm thinking that many cases would be just lerping 0.0 to 1.0, 255.0, 1000.0, or similar "small" values.</p>



<a name="244094646"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244094646" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244094646">(Jun 28 2021 at 01:32)</a>:</h4>
<p>Searching (will edit this message a few more times):</p>
<div class="codehilite"><pre><span></span><code>    lerp(0.000000029818942, 724085.75, 994951.9) = 724085.7
    lerp(0.000000029809552, 52037.652, 61402.95) = 52037.65
    lerp(0.00000002982163, 2636.042, 3392.6443) = 2636.0417
    lerp(0.000000029833707, 696.9417, 952.48224) = 696.94165
    lerp(0.000000029841495, 64.93388, 94.82493) = 64.933876
    lerp(0.000000029802916, 8.089652, 9.701944) = 8.089651
</code></pre></div>



<a name="244094731"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244094731" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244094731">(Jun 28 2021 at 01:34)</a>:</h4>
<p>So, yeah, even with reasonable values, a really small <code>t</code> can escape the bound</p>



<a name="244094793"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244094793" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244094793">(Jun 28 2021 at 01:36)</a>:</h4>
<p>To be clear, this is testing <code>((1.0 - t) * v0) + (t * v1)</code></p>



<a name="244094996"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244094996" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244094996">(Jun 28 2021 at 01:42)</a>:</h4>
<p>I'm now <a href="https://play.rust-lang.org/?version=stable&amp;mode=release&amp;edition=2018&amp;gist=2b4f68d05e2b3be5fb9e650072e8748b">burning my CPU</a> trying to show a bound of approximately 2 ULP, comparing against <a href="https://math.stackexchange.com/a/2969873/573727">what should be an exact calculation</a>, summed at twice the precision.</p>



<a name="244095008"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244095008" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244095008">(Jun 28 2021 at 01:42)</a>:</h4>
<p>Not a proof, but experimental results.</p>



<a name="244098980"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244098980" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244098980">(Jun 28 2021 at 03:37)</a>:</h4>
<p>Final count: I checked over 15000 different increasing min/max pairs for all values of t, and found a maximum deviation of 2 ULP from the error-corrected lerp. 94% of checked argument triples had no deviation from the error-corrected value; 6% deviated by 1 ULP; and 0.0003% varied by 2 ULP.</p>



<a name="244102310"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244102310" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244102310">(Jun 28 2021 at 04:59)</a>:</h4>
<p>blasted floating point</p>



<a name="244133985"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244133985" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Clar Fon <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244133985">(Jun 28 2021 at 12:04)</a>:</h4>
<p>mind sharing the code you've been using to find counterexamples? I made similar code at some point but it kind of sucked and used a jank (MIN..=MAX) =&gt; (0.0..=1.0) mapping to get it working with proptest</p>



<a name="244134098"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244134098" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Clar Fon <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244134098">(Jun 28 2021 at 12:05)</a>:</h4>
<p>from what I gathered, the C++ specification for lerp was proposed given a very specific implementation that could not possibly match all criteria they added, so no matter what, some of those criteria aren't going to make the cut</p>



<a name="244134162"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244134162" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Clar Fon <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244134162">(Jun 28 2021 at 12:05)</a>:</h4>
<p>my main thought was that we'd look for a reasonable subset that has a reasonable implementation with minimal branching</p>



<a name="244134236"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244134236" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Clar Fon <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244134236">(Jun 28 2021 at 12:06)</a>:</h4>
<p>(for example, I believe that the glibc implementation isn't monotonic)</p>



<a name="244153987"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244153987" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244153987">(Jun 28 2021 at 14:35)</a>:</h4>
<p><span class="user-mention silent" data-user-id="330161">Clar Fon</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244133985">said</a>:</p>
<blockquote>
<p>mind sharing the code you've been using to find counterexamples?</p>
</blockquote>
<p>Most recent: <a href="https://play.rust-lang.org/?version=stable&amp;mode=release&amp;edition=2018&amp;gist=2b4f68d05e2b3be5fb9e650072e8748b">https://play.rust-lang.org/?version=stable&amp;mode=release&amp;edition=2018&amp;gist=2b4f68d05e2b3be5fb9e650072e8748b</a><br>
It's not pretty, but it works. Just adding extra checks in the loop to check other properties.</p>



<a name="244161744"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244161744" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Clar Fon <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244161744">(Jun 28 2021 at 15:27)</a>:</h4>
<p>ugly code in this situation is better than no code <span aria-label="stuck out tongue" class="emoji emoji-1f61b" role="img" title="stuck out tongue">:stuck_out_tongue:</span></p>



<a name="244171695"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244171695" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244171695">(Jun 28 2021 at 16:37)</a>:</h4>
<p>I'm increasingly skeptical that something like this that isn't close to being standardized in industry usage is a fit for the standard library. getting all the rust-based libs to agree to use a single implementation would give confidence that this should be added to std</p>



<a name="244171956"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244171956" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Clar Fon <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244171956">(Jun 28 2021 at 16:39)</a>:</h4>
<p>Its existence is standardised in industry, but its details are not</p>



<a name="244172170"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244172170" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244172170">(Jun 28 2021 at 16:41)</a>:</h4>
<p>yes, which means I think it's still a promising avenue to pursue, but it needs consensus from existing library users. the stdlib doesn't want to dictate standards, it just wants to legitimize existing widespread patterns</p>



<a name="244172255"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244172255" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244172255">(Jun 28 2021 at 16:42)</a>:</h4>
<p>at best, as it stands it seems like you would not be able to get away with a one-size-fits-all solution, and would need to have several varieties of this function</p>



<a name="244172877"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244172877" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244172877">(Jun 28 2021 at 16:47)</a>:</h4>
<p>this is not to delegitimize the amount of work you have done so far, which is impressive, thoughtful, and thorough. I just think the problem space might not be ready for a solution to be set in stone at this point in time</p>



<a name="244174381"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244174381" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244174381">(Jun 28 2021 at 16:59)</a>:</h4>
<p>If you think that the writers of all the math libraries will agree with each other on their own and then that one answer should be imported to the standard library, i think you're missing a key factor in the psychology of people who go off and make their own entire math library.</p>



<a name="244174538"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244174538" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244174538">(Jun 28 2021 at 17:00)</a>:</h4>
<p>you appear to be arguing that people can't be convinced to use a single implementation, which strikes me as an implicit argument against adding this to std</p>



<a name="244174659"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244174659" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244174659">(Jun 28 2021 at 17:01)</a>:</h4>
<p>Well, no</p>



<a name="244174762"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244174762" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244174762">(Jun 28 2021 at 17:01)</a>:</h4>
<p>There's zero value at all for math lib writers to have interop with each other. None whatsoever. However, there's value to users to have a standard way to to things. The standard library exists to set a standard that people are expected to conform to or have a good reason for not conforming to.</p>



<a name="244174964"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244174964" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244174964">(Jun 28 2021 at 17:03)</a>:</h4>
<p>your talk of psychology makes it sound as though you think people are irrationally averse to the proposition of converging on a single implementation, which suggests that they won't be bothered be not having a good reason for not conforming to it</p>



<a name="244175213"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244175213" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244175213">(Jun 28 2021 at 17:04)</a>:</h4>
<p>I don't think they're <em>irrationally</em> averse, I just think there's nothing by default that's actually giving people any reason to do it the same way anyone else is doing it.</p>



<a name="244175558"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244175558" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244175558">(Jun 28 2021 at 17:07)</a>:</h4>
<p>then that suggests to me that they can be reasoned with and convinced to use a single implementation, and I further suggest that the next step of action is to do so external to std</p>



<a name="244176670"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244176670" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244176670">(Jun 28 2021 at 17:15)</a>:</h4>
<p>Send a PR to various libraries changing out their implementation of lerp for the proposed std implementation (the actual shape of their API is irrelevant to this phase and shouldn’t change in these PRs). Point them to this thread/issue and tell them that it’s part of a broader effort to include a lerp in std, and invite them to comment. If they have no objections to the PR, then that adds weight to the value of this proposal. If they do have objections, then collect them, determine if they’re reasonable/actionable, and take them into account in the proposal.</p>



<a name="244177375"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244177375" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244177375">(Jun 28 2021 at 17:20)</a>:</h4>
<p>nalgebra, euclid, emath, and ultraviolet all currently use <code>(1-t)v0</code>. glam, cgmath, and kurbo use <code>t(v1-v0)</code>. vek provides both.</p>



<a name="244191559"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244191559" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244191559">(Jun 28 2021 at 19:10)</a>:</h4>
<p>What does vek call the two different versions?</p>



<a name="244196370"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244196370" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244196370">(Jun 28 2021 at 19:55)</a>:</h4>
<p>seems to be <code>lerp</code> and <code>lerp_precise</code>, <a href="https://docs.rs/vek/0.15.1/vek/ops/trait.Lerp.html">https://docs.rs/vek/0.15.1/vek/ops/trait.Lerp.html</a></p>



<a name="244202159"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244202159" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244202159">(Jun 28 2021 at 20:44)</a>:</h4>
<p>Tested the same amount of lerps with the <code>t(v1-v0)</code> method, though with new random min/max pairs. That gave me 99.5% 0 ULP deviation from error-corrected, 0.5% 1 ULP deviation, and 0.00004% 2 ULP deviation.</p>



<a name="244202373"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244202373" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244202373">(Jun 28 2021 at 20:46)</a>:</h4>
<p>Based on this (scuffed) probabilistic test, it suggests that <code>v0 + t * (v1 - v0)</code> is actually more accurate than <code>(1 - t) * v0 + t * v1</code>.</p>



<a name="244202401"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244202401" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244202401">(Jun 28 2021 at 20:46)</a>:</h4>
<p>And to be clear, this was with no explicit FMA operations.</p>



<a name="244202484"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244202484" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244202484">(Jun 28 2021 at 20:47)</a>:</h4>
<p>I... honestly don't know which I prefer anymore</p>



<a name="244202670"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244202670" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244202670">(Jun 28 2021 at 20:49)</a>:</h4>
<p>Though I should clarify that my "precise" calculation is still limited by the precision of the computer, it just attempts to capture the error in each step and add them back in at the end.</p>



<a name="244203412"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244203412" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244203412">(Jun 28 2021 at 20:56)</a>:</h4>
<p><span class="user-mention silent" data-user-id="132829">Christopher Durham</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244202373">said</a>:</p>
<blockquote>
<p>Based on this (scuffed) probabilistic test, it suggests that <code>v0 + t * (v1 - v0)</code> is actually more accurate than <code>(1 - t) * v0 + t * v1</code>.</p>
</blockquote>
<p>yes, that should be accurate. it has fewer operations that will cause rounding — the issue is that it isn't precise at t == 1, which can be a footgun</p>



<a name="244203803"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244203803" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244203803">(Jun 28 2021 at 20:59)</a>:</h4>
<p>Yeah, though given that the <strong><em>exact</em></strong> formula still isn't <strong><em>bounded</em></strong> nor <strong><em>consistent</em></strong>, I'm not exactly certain how valuable a property that is</p>



<a name="244203948"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244203948" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244203948">(Jun 28 2021 at 21:00)</a>:</h4>
<p>Did anybody consider adding a couple bits to the floats to hold the intermediate results?!</p>



<a name="244204218"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244204218" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244204218">(Jun 28 2021 at 21:02)</a>:</h4>
<p>While useful for testing deviation, adding bits is not all that practical in practice, since while for scalar <code>f32</code> it'd be "free" (assuming <code>f32</code> and <code>f64</code> are "the same speed," which isn't a given), once you're packing multiple simd lanes adding bits becomes things you can't really do</p>



<a name="244204253"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244204253" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244204253">(Jun 28 2021 at 21:03)</a>:</h4>
<p><span class="user-mention silent" data-user-id="132829">Christopher Durham</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244203803">said</a>:</p>
<blockquote>
<p>Yeah, though given that the <strong><em>exact</em></strong> formula still isn't <strong><em>bounded</em></strong> nor <strong><em>consistent</em></strong>, I'm not exactly certain how valuable a property that is</p>
</blockquote>
<p>Like, for example, <code>(uint8_t) Lerp( Clamp( t, 0, 1 ), 0, 255 )</code>&lt;sub&gt;C&lt;/sub&gt; isn't guaranteed sound for all <code>t</code>, because the <code>Lerp</code> isn't bounded with either formula, you have to <code>(uint8_t) Clamp( Lerp( t, 0, 255 ), 0, 255 )</code> instead</p>



<a name="244204401"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244204401" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244204401">(Jun 28 2021 at 21:04)</a>:</h4>
<p>I was taking shots at f80 and the horror that x86's fpu was in the past ^^</p>



<a name="244204480"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244204480" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244204480">(Jun 28 2021 at 21:05)</a>:</h4>
<p>If all you care about is a single precise result it's not a horrible idea in isolation</p>



<a name="244204651"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244204651" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244204651">(Jun 28 2021 at 21:06)</a>:</h4>
<p>(Now I have to, of course, bring up the <a href="https://twitter.com/mycoliza/status/1031048252152369152?s=20"><code>long double</code></a>)</p>
<div class="inline-preview-twitter"><div class="twitter-tweet"><a href="https://twitter.com/mycoliza/status/1031048252152369152?s=20"><img class="twitter-avatar" src="https://uploads.zulipusercontent.net/850b7fef7fa746078748dc4a8a544f29fc9882f8/68747470733a2f2f7062732e7477696d672e636f6d2f70726f66696c655f696d616765732f313035373238343830343138303233383333372f4468777935756d705f6e6f726d616c2e6a7067"></a><p><a href="https://twitter.com/ManishEarth">@ManishEarth</a> <a href="https://twitter.com/myrrlyn">@myrrlyn</a> <a href="https://twitter.com/iximeow">@iximeow</a> @adam_n_p <a href="https://twitter.com/hdevalence">@hdevalence</a> <a href="https://twitter.com/isislovecruft">@isislovecruft</a> <a href="https://twitter.com/mgattozzi">@mgattozzi</a> <a href="https://twitter.com/havvy">@havvy</a> <a href="https://twitter.com/Sunjay03">@Sunjay03</a> @6b766e <a href="https://twitter.com/steveklabnik">@steveklabnik</a> implemented, naturally, as the sum of two IEEE 754 double-precision numbers</p><span>- 𓃭𓇋𓊃𓄿𓁐 (@mycoliza)</span></div></div>



<a name="244205348"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244205348" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244205348">(Jun 28 2021 at 21:13)</a>:</h4>
<p>BTW, got an answer on <a href="https://math.stackexchange.com/a/4185537/573727">https://math.stackexchange.com/a/4185537/573727</a>; TL;DR theoretical max ULP deviance for <code>(1-t)</code> version is around 2 + (cry if very big <code>v0</code> and very small <code>v1</code>).</p>



<a name="244205625"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244205625" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244205625">(Jun 28 2021 at 21:15)</a>:</h4>
<p>I'm going to be highly amused if <span class="user-mention" data-user-id="271719">@Mario Carneiro</span> answered that question without even realizing it was Rust-related :P</p>



<a name="244206064"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244206064" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244206064">(Jun 28 2021 at 21:18)</a>:</h4>
<p>full disclosure: the question was brought to my attention earlier in this thread, although I have answered questions like that in the past on MSE</p>



<a name="244206130"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244206130" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244206130">(Jun 28 2021 at 21:18)</a>:</h4>
<p>As far as I can tell, it's a good answer</p>



<a name="244206166"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244206166" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244206166">(Jun 28 2021 at 21:19)</a>:</h4>
<p>it would be good to see whether there are any actual inputs that demonstrate that the bound is approximately tight</p>



<a name="244206201"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244206201" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244206201">(Jun 28 2021 at 21:19)</a>:</h4>
<p>in particular, whether the relative accuracy really does take a nose dive when the output is supposed to be small</p>



<a name="244206328"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244206328" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244206328">(Jun 28 2021 at 21:20)</a>:</h4>
<p><del>Well, uh, <code>thread 'main' panicked at 'lerp(1, 340282350000000000000000000000000000000, 0.00000011920929) had a deviation of 872415232 ULP', src\main.rs:126:13</code></del></p>



<a name="244206353"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244206353" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244206353">(Jun 28 2021 at 21:21)</a>:</h4>
<p>Wait that was the <code>(v1-v0)</code> impl</p>



<a name="244206667"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244206667" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244206667">(Jun 28 2021 at 21:24)</a>:</h4>
<p>Manually testing, I didn't find anything beyond a 2 ULP variance for the <code>(1-t)</code> impl</p>



<a name="244206697"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244206697" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244206697">(Jun 28 2021 at 21:24)</a>:</h4>
<p>I might let my computer do a random search with very small <code>v1</code> and very large <code>v0</code> again tomorrow but I need to use my cores for the rest of today</p>



<a name="244206762"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244206762" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244206762">(Jun 28 2021 at 21:25)</a>:</h4>
<p>This does give me more confidence that <code>(1-t)</code> behaves "better" for extreme inputs, though</p>



<a name="244207040"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244207040" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244207040">(Jun 28 2021 at 21:28)</a>:</h4>
<p>This one has a good chance of just being error in my error-corrected calculation, but for the literal edgest of cases <code>'lerp(0.000000000000000000000000000000000000000000001, 340282350000000000000000000000000000000, -340282350000000000000000000000000000000) had a deviation of 4194305 ULP', src\main.rs:126:13</code> (<code>(1-t)</code> lerp)</p>



<a name="244207076"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244207076" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244207076">(Jun 28 2021 at 21:28)</a>:</h4>
<p>Note that the analysis I gave is wrong for denormal numbers because relative error is larger in that case</p>



<a name="244207096"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244207096" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244207096">(Jun 28 2021 at 21:29)</a>:</h4>
<p>I have no good way to skip denormals in my sweep <span aria-label="upside down" class="emoji emoji-1f643" role="img" title="upside down">:upside_down:</span></p>



<a name="244207154"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244207154" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244207154">(Jun 28 2021 at 21:29)</a>:</h4>
<p>Though I can just start at the other end... <code>thread 'main' panicked at 'lerp(0.99999994, 340282350000000000000000000000000000000, -340282350000000000000000000000000000000) had a deviation of 2143289341 ULP', src\main.rs:130:13</code></p>



<a name="244207161"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244207161" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244207161">(Jun 28 2021 at 21:29)</a>:</h4>
<p><span class="user-mention silent" data-user-id="132829">Christopher Durham</span> <a href="#narrow/stream/219381-t-libs/topic/lerp.20API.20design/near/244206762">said</a>:</p>
<blockquote>
<p>This does give me more confidence that <code>(1-t)</code> behaves "better" for extreme inputs, though</p>
</blockquote>
<p>There might be a reason for that: The problematic assumption is that <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mo>⊕</mo><mi>b</mi><mo>=</mo><mo stretchy="false">(</mo><mi>a</mi><mo>+</mo><mi>b</mi><mo stretchy="false">)</mo><mo stretchy="false">(</mo><mn>1</mn><mo>±</mo><mi>ϵ</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">a\oplus b=(a+b)(1\pm\epsilon)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⊕</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">b</span><span class="mclose">)</span><span class="mopen">(</span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">±</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">ϵ</span><span class="mclose">)</span></span></span></span>, which is a very bad estimate if <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi></mrow><annotation encoding="application/x-tex">a</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">a</span></span></span></span> is much bigger than <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>b</mi></mrow><annotation encoding="application/x-tex">b</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">b</span></span></span></span> so that <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mi>ϵ</mi></mrow><annotation encoding="application/x-tex">a\epsilon</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">a</span><span class="mord mathnormal">ϵ</span></span></span></span> is lots of ulps. I think the real estimate has this error bounded by <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>b</mi></mrow><annotation encoding="application/x-tex">b</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">b</span></span></span></span> at least</p>



<a name="244207168"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244207168" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244207168">(Jun 28 2021 at 21:29)</a>:</h4>
<p>This is also a sign change</p>



<a name="244207579"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244207579" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244207579">(Jun 28 2021 at 21:34)</a>:</h4>
<p>There's also a decent chance that my "ULP variation" code is wrong around denormals and/or sign changes tbh</p>



<a name="244262863"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244262863" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Cameron Hart <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244262863">(Jun 29 2021 at 10:55)</a>:</h4>
<p>I didn't see it covered here, I believe precise refers to getting v = v1 when t = 1. See <a href="https://en.wikipedia.org/wiki/Linear_interpolation#Programming_language_support">https://en.wikipedia.org/wiki/Linear_interpolation#Programming_language_support</a>. Also covers monotonic properties of both.</p>



<a name="244317758"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/lerp%20API%20design/near/244317758" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/lerp.20API.20design.html#244317758">(Jun 29 2021 at 17:30)</a>:</h4>
<p>I've been using <strong><em>bold italic</em></strong> when referring specifically to the properties as I defined on the tracking issue: <a href="https://github.com/rust-lang/rust/issues/86269#issuecomment-869108301">https://github.com/rust-lang/rust/issues/86269#issuecomment-869108301</a></p>
<p>These are the properties as described by the C++ paper as well.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>